package org.sean.framework.logstash.init;

import lombok.extern.slf4j.Slf4j;
import org.sean.framework.logstash.logging.LogConstants;
import org.sean.framework.util.ObjectUtil;
import org.sean.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.bootstrap.config.BootstrapPropertySource;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.cloud.bootstrap.config.SimpleBootstrapPropertySource;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 初始化Kafka配置
 *
 * @author xielei
 */
@Slf4j
public class LogstashInitializer implements Ordered,ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Autowired(required = false)
    private List<PropertySourceLocator> propertySourceLocators = new ArrayList<>();

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        List<PropertySource<?>> composite = new ArrayList<>();
        AnnotationAwareOrderComparator.sort(this.propertySourceLocators);
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        for (PropertySourceLocator locator : this.propertySourceLocators) {
            Collection<PropertySource<?>> source = locator.locateCollection(environment);
            if (ObjectUtil.isEmpty(source)) {
                continue;
            }
            List<PropertySource<?>> sourceList = new ArrayList<>();
            for (PropertySource<?> p : source) {
                if (p instanceof EnumerablePropertySource) {
                    EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) p;
                    sourceList.add(new BootstrapPropertySource<>(enumerable));
                } else {
                    sourceList.add(new SimpleBootstrapPropertySource<>(p));
                }
            }
            composite.addAll(sourceList);
        }

        composite.forEach(item -> environment.getPropertySources().addFirst(item));

        setProperty(environment);
    }

    public static void setProperty(ConfigurableEnvironment environment) {
        String server = environment.getProperty(LogConstants.LOGSTASH_SERVER);
        if (!System.getProperties().containsKey(LogConstants.LOGSTASH_SERVERS_PROPERTY) && StringUtil.isNotEmpty(server)) {
            System.setProperty(LogConstants.LOGSTASH_SERVERS_PROPERTY, server);
        }

        String name = environment.getProperty(LogConstants.APP_NAME);
        if (!System.getProperties().containsKey(LogConstants.APP_NAME_PROPERTY) && StringUtil.isNotEmpty(name)) {
            System.setProperty(LogConstants.APP_NAME_PROPERTY, name);
        }
    }
}
